import { useEffect, useRef, useState } from "react";
import Taro, { useReachBottom, useRouter } from "@tarojs/taro";
import { PageContainer, ScrollView, View } from "@tarojs/components";
import pick from "lodash-es";

import { useBoolean, useMap, useReactive, useUpdateEffect } from "ahooks";

import ByRow from "@/components/ui/ByRow";
import ByText from "@/components/ui/ByText";
import Page from "@/components/common/Page";
import ByIcon from "@/components/ui/ByIcon";
import Divider from "@/components/app/Divider";
import ByImage from "@/components/ui/ByImage";
import ByButton from "@/components/ui/ByButton";
import ListView from "@/components/app/ListView";
import ByCounter from "@/components/ui/ByCounter";
import BySearchBar from "@/components/ui/BySearchBar";
import PopupContainer from "@/components/app/PopupContainer";

import ApiBudget from "@/api/budget";
import useList from "@/hooks/useList";
import useFetch from "@/hooks/useFetch";
import ApiMaterial from "@/api/material";

import {
  MaterialClassItem,
  MaterialDetailDTO,
  MaterialInfo,
} from "@/types/material";

type ProductProps = {
  num?: number;
  source: MaterialInfo;
  selected?: MaterialDetailDTO;
};

type ProductEvent = {
  onChange?: (num: number) => void;
};

const Products = ({ num, source, onChange }: ProductProps & ProductEvent) => {
  return (
    <View className="flex bg-white rounded-xl mx-3 my-2 p-4 shadow-black-1">

      <View className="relative">
        <ByImage
          src=""
          size={180}
          circle={false}
          lazyLoad={true}
          className="flex-none shadow-black-1"
        />

        <View className="absolute top-0 left-0 px-1 py-0.5 text-xs bg-primary-light z-10 rounded-tl-md rounded-br-md">{source.brandCategory}</View>
      </View>

      <View className="flex-auto ml-4 min-w-0">
        <ByText block size="sm">
          {source.materialName}
        </ByText>

        <ByText block size="xs" type="second" className="flex flex-wrap items-center my-1">
          {
            source.materialBrand &&
            <>
              {source.materialBrand}
              <Divider horizontal />
            </>
          }
          {
            source.spec &&
            <>
              {source.spec}
              <Divider horizontal />
            </>
          }
          <>{source.stockName}</>
        </ByText>

        <ByText block size="xs">{source.supplyName}</ByText>

        <View className="flex justify-between items-center mt-2">
          <ByText block size="sm">
            承包价：￥{source.contractPrice} / {source.unit}
          </ByText>

          <ByCounter className="w-[200px]" precision={2} value={num} onChange={onChange} />
        </View>
      </View>
    </View>
  );
};



const PopupClassList = ({ list, onChoose, onCancel }) => {

  return (
    <PopupContainer title="选择分类" onCancel={onCancel}>
      <ScrollView scrollY className="h-[70vh]">
        {
          list.map((item, index) => (
            <View className="flex mx-4 my-2 p-3 items-center rounded-lg shadow-black-1" key={index}
              onClick={() => onChoose(item)}
            >
              <View className="flex-auto">
                {item.nameText}
              </View>
              <ByIcon name="ArrowRight" className="text-primary" />
            </View>
          ))
        }
      </ScrollView>
    </PopupContainer>
  )

}

export default () => {
  const { params } = useRouter();
  const intentCustomerId = Number(params.intentCustomerId);

  // 购物车Map
  const [cartMap, cartMapHandle] = useMap<
    string,
    MaterialInfo & { applyQuantity: number }
  >();

  // 全量材料Map,用于方便读取JsNum等属性值
  const materialsMap = useRef<Map<string, any>>(new Map());

  useFetch(ApiBudget.getSpecialMaterialAndClass, {
    defaultParams: [{ intentCustomerId }],
    onSuccess({ list }) {
      list
        .map((e) => e.materialData)
        .flat(2)
        .forEach((item) => {
          materialsMap.current.set(item.materialCode, item);
        });
    },
  });

  const search = useReactive({
    keyword: "",
    isSpecial: true,
    materialClassCode: "",
  });


  // 获取材料分类
  const { list: classTreeList } = useList<MaterialClassItem>(
    ApiMaterial.classTree,
    {
      defaultParams: [{ materialProCode: "D", isSpecial: true, includeChildren: true }],
    }
  );

  // 分类列表
  const [classList, setClassList] = useState<any[]>([])

  // 处理数据
  function transformData(items: any[]): any[] {
    const result: any[] = [];

    function recurse(item: any, currentNames: string[] = [], currentCodes: string[] = []) {
      // 收集当前层级的name和code
      const names = [...currentNames, item.materialClassName];
      const codes = [...currentCodes, item.materialClassCode];

      // 如果没有子节点，就将当前路径加入结果
      if (!item.children || item.children.length === 0) {
        result.push({ name: names, code: codes, nameText: names.join("/") });
        return;
      }

      // 递归处理子节点
      item.children.forEach(child => recurse(child, names, codes));
    }

    // 处理每个根节点
    items.forEach(item => recurse(item));

    return result;
  }

  useUpdateEffect(() => {
    setClassList(transformData(classTreeList))
  }, [classTreeList])

  // 根据条件，获取材料列表
  const { loading, list, resetToFirst, nextPage } = useList<MaterialInfo>(
    ApiMaterial.list,
    { showLoading: true, defaultParams: [search] }
  );

  useReachBottom(nextPage)

  useUpdateEffect(() => {
    resetToFirst(search);
  }, [search.keyword, search.materialClassCode]);

  // 添加数量
  const productChange = (num: number, target: MaterialInfo) => {
    const historyTarget = materialsMap.current.get(target.materialCode) || {};

    cartMapHandle.set(target.materialCode, {
      jsNum: 0,
      ...target,

      // 账单数量
      ...pick(historyTarget, ["billNum", "jsNum"]),

      listType: 1,
      budgetRemark: "",
      applyQuantity: num,
    });
  };

  const handleConfirm = async () => {
    Taro.navigateTo({
      url: `cart?intentCustomerId=${intentCustomerId}`,
      events: {
        updateCartOriginData(data) {
          // 先重置
          cartMapHandle.reset();

          [...data.get(0)].forEach((item) =>
            productChange(item.applyQuantity, item)
          );
        },
      },
      success(res) {
        res.eventChannel.emit("accpetBudgetDetails", {
          map: new Map().set(0, new Set(cartMap.values())),
          materielCategory: 7,
          materielCategoryText: "自选",
          // details: [...cartMap.values()],
        });
      },
    });
  };

  const [selected, setSelected] = useState<any>()
  const [visible, { setTrue, setFalse }] = useBoolean();
  const handleChoose = (item) => {
    setFalse()
    setSelected(item)
    search.materialClassCode = item.code.at(-1)
  }

  return (
    <>
      <Page
        footerSticky
        slotHeader={
          <View className="bg-white p-2 shadow-black-1">

            <View className="flex items-center shadow-black-1 p-3 mb-3 rounded-md" onClick={setTrue}>
              <View className="flex-auto">{selected?.nameText || '选择分类'}</View>
              <ByIcon name="ArrowBottom" />
            </View>

            <BySearchBar
              circle
              height="64rpx"
              placeholder="搜索"
              onClear={() => (search.keyword = "")}
              onConfirm={(e) => (search.keyword = e)}
            />
          </View>
        }
        slotFooter={
          <ByRow content="between" align="center">
            <ByText size="sm" type="third">
              已选：{cartMap.size}类材料
            </ByText>

            <ByButton className="mr-0" onClick={handleConfirm}>
              提交
            </ByButton>
          </ByRow>
        }
      >

        <ListView loading={loading} isEmpty={list.length == 0}>
          {list.map((item) => (
            <Products
              source={item}
              key={item.materialCode}
              num={
                cartMapHandle.get(item.materialCode)?.applyQuantity || 0
              }
              onChange={(e) => productChange(e, item)}
            />
          ))}
        </ListView>
      </Page>

      <PageContainer show={visible} round onAfterLeave={setFalse}>
        <PopupClassList list={classList} onChoose={handleChoose} onCancel={setFalse} />
      </PageContainer>
    </>
  );
};
